﻿using System.Windows.Forms;
using System.Collections.Generic;
using System.IO;
using System;
using System.Reflection;
using System.Drawing;
using Editor.Elements;
using Editor.Main_Windows;
using Editor.PageControls;
using Editor.Utilities;

namespace Editor
{
    public partial class EditorForm: Form
    {
        // Mdi Forms
        private ControlList controlList;
        private ToolBox toolBox;
        private Canvas canvas;
        private ProjectExplorer projectExplorer;
        
        // Singleton instance
        private static EditorForm _instance;

        private EditorForm()
        {
            InitializeComponent();
        }

        public static EditorForm Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new EditorForm();

                return _instance;
            }
            set { _instance = value; }
        }

        public static PropertiesFormBase PropertiesForm { get; set; }
        public static Project CurrentProject { get; set; }
        public static Page CurrentPage { get; set; }
        public static Page PreviousPage { get; set; }

        public static TreeNode SelectedNode
        {
            get { return Instance.projectExplorer.SelectedNode; }
            set { Instance.projectExplorer.SelectedNode = value; }
        }

        public static TreeNodeCollection TreeNodes
        {
            get { return Instance.projectExplorer.TreeNodes; }
        }

        public static PageControl ToolBoxPickedControl
        {
            get 
            {
                if (Instance.toolBox == null) 
                    return null;

                return Instance.toolBox.SelectedControl; 
            }
            set { Instance.toolBox.SelectedControl = value; }
        }

        public string PageName
        {
            get { return canvas.Text; }
            set { canvas.Text = value; }
        }

        public static bool Relocating { get; set; }
        public static bool Copying { get; set; }

        public static bool IsElementNameAvailable(string name)
        {
            foreach (PageControl pc in CurrentPage.Controls)
                if (pc.Name.Equals(name))
                    return false;
            return true;
        }

        public static string GenerateName(string prefix)
        {
            int number = 0;

            while (!IsElementNameAvailable(prefix + ++number)) ;

            return prefix + number;
        }

        public static void ExplorerExpandAll()
        {
            Instance.projectExplorer.ExplorerExpandAll();
        }

        public static void SwitchToPage(Page page)
        {
            PageProperties = Instance.canvas.SwitchToPage(page);
        }

        public static void SwitchToSelectedPage()
        {
            PageProperties = Instance.canvas.SwitchToSelectedPage();
        }

        public static void LoadProjectToExplorer(Project project)
        {
            Instance.projectExplorer.LoadProjectToExplorer(project);
        }

        public static void LoadCurrentProjectToExplorer()
        {
            Instance.projectExplorer.LoadProjectToExplorer(CurrentProject);
        }

        public static void RefreshCanvas()
        {
            Instance.canvas.Refresh();
        }

        public static void UpdateControlList()
        {
            Instance.controlList.UpdateList();
        }

        public static void ChangePropertiesForm(PropertiesFormBase pfb)
        {
            RefreshCanvas();

            if (PropertiesForm != null && PropertiesForm.ControlName
                == PageControl.SelectedControl.Name)
                return;

            if (PropertiesForm != null)
                PropertiesForm.Visible = false;
            PropertiesForm = pfb; 
        }

        public static void RemoveControl(PageControl pageControl)
        {
            Instance.canvas.RemoveControl(pageControl);
            RefreshCanvas();
        }

        public static void RemoveSelectedControl()
        {
            RemoveControl(PageControl.SelectedControl);
            IsSaved = false;
        }
        
        private void Form1_Load(object sender, System.EventArgs e)
        {
            ProjectExplorerChecked = ProjectExplorerEnabled = false;
            PageProperties = false;
            openFileDialogProject.InitialDirectory = Directory.GetCurrentDirectory();
            CurrentLanguage = SupportedLanguages[0];
        }

        private void kapatToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            Close();
        }

        public static string[] PageControls
        {
            get
            {
                if (CurrentPage == null) return null;

                List<string> controlNames = new List<string>();

                foreach (PageControl pc in CurrentPage.Controls)
                    controlNames.Add(pc.Name);

                return controlNames.ToArray();
            }
        }

        public static readonly string[] SupportedLanguages =
            new string[] { "Türkçe", "English", "Deutsch" };

        public static string CurrentLanguage { get; set; }

        public static string DefaultLanguage
        {
            get
            {
                return SupportedLanguages[0];
            }
        }

        public static int CurrentLanguageIndex
        {
            get
            {
                for (int i = 0; i < SupportedLanguages.Length; ++i)
                    if (CurrentLanguage == SupportedLanguages[i])
                        return i;
                return -1;
            }
            set
            {
                if (value >= 0 && value < SupportedLanguages.Length)
                    CurrentLanguage = SupportedLanguages[value];    
            }
        }

        public static bool ControlListChecked
        {
            get { return Instance.bileşenlerToolStripMenuItem.Checked; }
            set { Instance.bileşenlerToolStripMenuItem.Checked = value; }
        }

        public static bool ToolBoxChecked
        {
            get { return Instance.araçÇubuğuToolStripMenuItem.Checked; }
            set { Instance.araçÇubuğuToolStripMenuItem.Checked = value; }
        }

        public static bool CanvasChecked
        {
            get { return Instance.çalışmaAlanıToolStripMenuItem.Checked; }
            set { Instance.çalışmaAlanıToolStripMenuItem.Checked = value; }
        }

        public static bool ProjectExplorerChecked
        {
            get { return Instance.projeDiziniToolStripMenuItem.Checked; }
            set { Instance.projeDiziniToolStripMenuItem.Checked = value; }
        }

        public static bool ProjectExplorerEnabled
        {
            get { return Instance.projeDiziniToolStripMenuItem.Enabled; }
            set { Instance.projeDiziniToolStripMenuItem.Enabled = value; }
        }

        public static bool CanvasEnabled
        {
            get { return Instance.çalışmaAlanıToolStripMenuItem.Enabled; }
            set { Instance.çalışmaAlanıToolStripMenuItem.Enabled = value; }
        }

        public static bool ToolBoxEnabled
        {
            get { return Instance.araçÇubuğuToolStripMenuItem.Enabled; }
            set { Instance.araçÇubuğuToolStripMenuItem.Enabled = value; }
        }

        public static bool ControlListEnabled
        {
            get { return Instance.bileşenlerToolStripMenuItem.Enabled; }
            set { Instance.bileşenlerToolStripMenuItem.Enabled = value; }
        }

        public static bool ConvertToTemplateEnabled
        {
            get { return Instance.şablonaÇevirToolStripMenuItem.Enabled; }
            set { Instance.şablonaÇevirToolStripMenuItem.Enabled = value; }
        }

        public static bool SaveEnabled
        {
            get { return Instance.kaydetToolStripMenuItem.Enabled; }
            set { Instance.kaydetToolStripMenuItem.Enabled = value; }
        }

        public static bool PageProperties
        {
            set
            {
                CanvasEnabled = CanvasChecked = value;
                ToolBoxEnabled = ToolBoxChecked = value;
                ControlListEnabled = ControlListChecked = value;
                ConvertToTemplateEnabled = value;
                SaveEnabled = value;
            }
        }

        public static bool IsSaved
        {
            get
            {
                return CurrentProject.IsSaved;
            }
            set
            {
                CurrentProject.IsSaved = value;
            }
        }

        public static bool IsLoaded
        {
            get
            {
                return CurrentProject.IsLoaded;
            }
            set
            {
                CurrentProject.IsLoaded = value;
            }
        }

        private void araçÇubuğuToolStripMenuItem_Click(object sender, EventArgs e)
        {
            araçÇubuğuToolStripMenuItem.Checked = !araçÇubuğuToolStripMenuItem.Checked;
        }

        private void projeDiziniToolStripMenuItem_Click(object sender, EventArgs e)
        {
            projeDiziniToolStripMenuItem.Checked = !projeDiziniToolStripMenuItem.Checked;
        }

        private void çalışmaAlanıToolStripMenuItem_Click(object sender, EventArgs e)
        {
            çalışmaAlanıToolStripMenuItem.Checked = !çalışmaAlanıToolStripMenuItem.Checked;
        }

        private void bileşenlerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            bileşenlerToolStripMenuItem.Checked = !bileşenlerToolStripMenuItem.Checked;
        }

        private T setMdiChild<T>(T child, bool checkd)
            where T : Form, new()
        {
            T t = child;

            if (child == null || child.IsDisposed)
            {
                child = new T();
                child.MdiParent = this;
                t = child;
            }

            child.Visible = checkd;

            return t;
        }
        
        private void araçÇubuğuToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
        {
            toolBox = setMdiChild<ToolBox>(toolBox, araçÇubuğuToolStripMenuItem.Checked);
        }

        private void projeDiziniToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
        {
            projectExplorer = setMdiChild<ProjectExplorer>(projectExplorer, projeDiziniToolStripMenuItem.Checked);

            if (projectExplorer.TreeNodes == null || projectExplorer.TreeNodes.Count == 0)
                if (CurrentProject != null)
                    switchToProject(CurrentProject);

            if (projeDiziniToolStripMenuItem.Checked)
                projectExplorer.ExplorerExpandAll();
        }

        private void çalışmaAlanıToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
        {
            canvas = setMdiChild<Canvas>(canvas, çalışmaAlanıToolStripMenuItem.Checked);
        }

        private void bileşenlerToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
        {
            controlList = setMdiChild<ControlList>(controlList, bileşenlerToolStripMenuItem.Checked);
        }

        private void kaydetToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CurrentProject.Save();
        }

        /*
        private void şablonaÇevirToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TemplateContainer.SaveAsTemplate(CurrentPage);
        }
         * */

        private void switchToProject(Project newProject)
        {
            if (CurrentProject != null)
            {
                int indexOfDash = Text.LastIndexOf('-');

                if (indexOfDash >= 0)
                    Text = Text.Remove(indexOfDash - 1);
            }

            Text += " - " + newProject.DefaultName;
            CurrentProject = newProject;
            LoadCurrentProjectToExplorer();
        }

        private void refreshControls()
        {
            if (CurrentPage != null)
            {
                foreach (PageControl pc in CurrentPage.Controls)
                {
                    pc.UpdateInnerControl();
                }
            }
        }

        private void oluşturToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CreateForm projectCreateForm = new CreateForm("Proje Oluştur");

            if (projectCreateForm.ShowDialog() == DialogResult.OK)
            {
                if (CurrentProject != null)
                    PageProperties = false;

                Project newProject = new Project(projectCreateForm.Dictionary);

                ProjectExplorerEnabled = ProjectExplorerChecked = true;
                switchToProject(newProject);
                newProject.Save();
            }
        }

        private void açToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            if (openFileDialogProject.ShowDialog() == DialogResult.OK)
            {
                PageProperties = false;

                string fileName = openFileDialogProject.FileName;
                Project loadedProject = Project.Load(fileName);

                switchToProject(loadedProject);
                ProjectExplorerEnabled = ProjectExplorerChecked = true;
                ExplorerExpandAll();
            }
        }

        private void türkçeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            türkçeToolStripMenuItem.Checked = true;
            englishToolStripMenuItem.Checked = false;
            deutschToolStripMenuItem.Checked = false;
        }

        private void englishToolStripMenuItem_Click(object sender, EventArgs e)
        {
            englishToolStripMenuItem.Checked = true;
            türkçeToolStripMenuItem.Checked = false;
            deutschToolStripMenuItem.Checked = false;
        }

        private void deutschToolStripMenuItem_Click(object sender, EventArgs e)
        {
            deutschToolStripMenuItem.Checked = true;
            türkçeToolStripMenuItem.Checked = false;
            englishToolStripMenuItem.Checked = false;
        }

        private void türkçeToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
        {
            if (türkçeToolStripMenuItem.Checked)
            {
                CurrentLanguage = SupportedLanguages[0];
                refreshControls();
                RefreshCanvas();
                CurrentProject.UpdateParents();
                projectExplorer.RefreshTree();
            }
        }

        private void englishToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
        {
            if (englishToolStripMenuItem.Checked)
            {
                CurrentLanguage = SupportedLanguages[1];
                refreshControls();
                RefreshCanvas();
                CurrentProject.UpdateParents();
                projectExplorer.RefreshTree();
            }
        }

        private void deutschToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
        {
            if (deutschToolStripMenuItem.Checked)
            {
                CurrentLanguage = SupportedLanguages[2];
                refreshControls();
                RefreshCanvas();
                CurrentProject.UpdateParents();
                projectExplorer.RefreshTree();
            }
        }

        private void EditorForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (CurrentProject != null && !CurrentProject.IsSaved)
            {
                DialogResult dr = MessageBox.Show("Sayfa kaydedilmedi, kaydedip çıkmak istiyor musunuz?",
                   "Uyarı", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);

                switch (dr)
                {
                    case DialogResult.Cancel:
                        e.Cancel = true;
                        break;

                    case DialogResult.Yes:
                        CurrentProject.Save();
                        break;
                }
            }
        }

        private void projeTaşıyıcıToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (openFileDialogProject.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                CreateForm migratedProject = new CreateForm("Taşınan Sayfa Adı");

                if (migratedProject.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    if (CurrentProject != null)
                        PageProperties = false;

                    Project newProject = new Project(migratedProject.Dictionary);

                    Old.Project oldProject = XMLWorker<Old.Project>.DeserializeFromXML(openFileDialogProject.FileName);

                    oldProject.UpdateParents();

                    foreach (Old.Department dept in oldProject.ChildElements)
                    {
                        SDictionary<string> deptNames = new SDictionary<string>();

                        foreach (string language in SupportedLanguages)
                            deptNames[language] = dept.Name;

                        Department newDepartment = new Department(deptNames);

                        foreach (Old.Course cors in dept.ChildElements)
                        {
                            SDictionary<string> costNames = new SDictionary<string>();

                            foreach (string language in SupportedLanguages)
                                costNames[language] = cors.Name;

                            Course newCourse = new Course(costNames);

                            foreach (Old.Topic topc in cors.ChildElements)
                            {
                                SDictionary<string> topcNames = new SDictionary<string>();

                                foreach (string language in SupportedLanguages)
                                    topcNames[language] = topc.Name;

                                Topic newTopic = new Topic(topcNames);

                                foreach (Old.Subtopic subtopc in topc.ChildElements)
                                {
                                    SDictionary<string> subNames = new SDictionary<string>();

                                    foreach (string language in SupportedLanguages)
                                        subNames[language] = subtopc.Name;

                                    Subtopic newSubtopic = new Subtopic(subNames);

                                    foreach (Old.Page page in subtopc.ChildElements)
                                    {
                                        SDictionary<string> pageNames = new SDictionary<string>();

                                        foreach (string language in SupportedLanguages)
                                            pageNames[language] = page.Name;

                                        string basePath = openFileDialogProject.FileName;

                                        basePath = basePath.Substring(0, basePath.LastIndexOf(Path.DirectorySeparatorChar));
                                        basePath = basePath.Substring(0, basePath.LastIndexOf(Path.DirectorySeparatorChar));

                                        Old.Page fullPage = page.LoadBase(basePath);

                                        Page newPage = new Page(pageNames);
                                        PageControl newPageControl;

                                        foreach (Old.PageControl control in fullPage.Controls)
                                        {
                                            newPageControl = null;

                                            if (control is Old.PageLabel)
                                            {
                                                Old.PageLabel oldPageLabel = control as Old.PageLabel;
                                                PageLabel newPageLabel = new PageLabel();

                                                foreach (string language in SupportedLanguages)
                                                    newPageLabel.Dictionary[language] = oldPageLabel.Text;
                                                newPageLabel.BackColor = oldPageLabel.BackColor;
                                                newPageLabel.ForeColor = oldPageLabel.ForeColor;
                                                newPageLabel.Location = oldPageLabel.Location;
                                                newPageLabel.MaxWidth = oldPageLabel.MaxWidth;
                                                newPageLabel.Name = oldPageLabel.Name;
                                                newPageLabel.Size = oldPageLabel.Size;
                                                newPageLabel.TextFontSize = oldPageLabel.TextFontSize;
                                                newPageLabel.Visible = oldPageLabel.Visible;
                                                newPageControl = newPageLabel;
                                            }
                                            else if (control is Old.PageImageBox)
                                            {
                                                Old.PageImageBox oldImageBox = control as Old.PageImageBox;
                                                PageImageBox newPageImageBox = new PageImageBox();

                                                foreach (string language in SupportedLanguages)
                                                    newPageImageBox.Dictionary[language] = oldImageBox.ImageSerialized;
                                                newPageImageBox.BackColor = oldImageBox.BackColor;
                                                newPageImageBox.ForeColor = oldImageBox.ForeColor;
                                                newPageImageBox.Location = oldImageBox.Location;
                                                newPageImageBox.Name = oldImageBox.Name;
                                                newPageImageBox.Size = oldImageBox.Size;
                                                newPageImageBox.ScrollableSize = oldImageBox.ScrollableSize;
                                                newPageImageBox.IsLong = oldImageBox.IsLong;
                                                newPageImageBox.IsFormula = oldImageBox.IsFormula;
                                                newPageImageBox.TextFontSize = oldImageBox.TextFontSize;
                                                newPageImageBox.Visible = oldImageBox.Visible;
                                                newPageControl = newPageImageBox;
                                            }
                                            else if (control is Old.PageHideButton)
                                            {
                                                Old.PageHideButton oldHideButton = control as Old.PageHideButton;
                                                PageHideButton newPageHideButoon = new PageHideButton();

                                                foreach (string language in SupportedLanguages)
                                                    newPageHideButoon.Dictionary[language] = oldHideButton.Text;
                                                newPageHideButoon.BackColor = oldHideButton.BackColor;
                                                newPageHideButoon.ForeColor = oldHideButton.ForeColor;
                                                newPageHideButoon.Location = oldHideButton.Location;
                                                newPageHideButoon.Name = oldHideButton.Name;
                                                newPageHideButoon.Size = oldHideButton.Size;
                                                newPageHideButoon.TextFontSize = oldHideButton.TextFontSize;
                                                newPageHideButoon.HideControl = oldHideButton.HideControl;
                                                newPageHideButoon.Visible = oldHideButton.Visible;
                                                newPageControl = newPageHideButoon;
                                            }

                                            newPage.AddPageControl(newPageControl);
                                        }

                                        newSubtopic.AddChildElement(newPage);
                                    }

                                    newTopic.AddChildElement(newSubtopic);
                                }

                                newCourse.AddChildElement(newTopic);
                            }

                            newDepartment.AddChildElement(newCourse);
                        }

                        newProject.AddChildElement(newDepartment);
                    }

                    newProject.Save();

                    MessageBox.Show(oldProject.Name + " başarıyla aktarıldı!", "Başarı", MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                }
            }
        }
    }
}
